package ge.telasi.tasks.fixture;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;

/**
 * Fixture.
 *
 * @author dimitri
 */
public abstract class Fixture<T> {

    /**
	 * Map for storing fixture data.
	 */
	protected static Map<String, Map<String, ?>> DATA 
            = new HashMap<String, Map<String, ?>>();

	/**
	 * Clears fixture cache.
	 */
	public static void clearFixture() {
		DATA.clear();
	}

	/**
	 * Returns key under which data for this
	 * fixture is saved.
	 */
	protected String key() {
		return getClass().getName();
	}

	/**
	 * Each fixture class can be called only once.
	 * This flag indicates whether fixture was
	 * already called in this or another instance
	 * of this class.
	 */
	protected boolean isOnceCalled() {
		return DATA.containsKey(key());
	}

	/**
	 * Executes this fixture and returns all
	 * the data in form of named entities.
	 */
	protected abstract Map<String, T> execute(EntityManager em);

	/**
	 * Runs this fixture.
	 */
	protected void runFixture(EntityManager em) {
		if (!isOnceCalled()) {
			DATA.put(key(), execute(em));
		}
	}
	
	// -- Public interface

	/**
	 * Get entity by it's name.
	 */
	public T getEntity(EntityManager em, String name) {
		runFixture(em);
		return (T) DATA.get(key()).get(name);
	}

	public Collection<T> getEntities(EntityManager em) {
		runFixture(em);
		return (Collection<T>) DATA.get(key()).values();
	}

}
